#define __QYQ_ARITHMETIC_FILTER_C_
#include "qyq_arithmetic_filter.h"

/*
        限幅滤波算法
    old_value：旧的值
    new_value：新的值
    deviation_value：偏差值
    reture_value：返回值
*/
void qyq_arithmetic_limiting_filter(int32_t old_value, int32_t new_value, int32_t deviation_value, int32_t *reture_value)
{
    if (old_value < new_value)
    {
        if ((new_value - old_value) > deviation_value)
        {
            *reture_value = old_value;
        }
        else
        {
            *reture_value = new_value;
        }
    }
    else
    {
        if ((old_value - new_value) > deviation_value)
        {
            *reture_value = old_value;
        }
        else
        {
            *reture_value = new_value;
        }
    }
}

/*
        中位值滤波法
    buf：数据列表
    number：数据数量，为奇数
    reture_value：返回值
*/
void qyq_arithmetic_median_filter(int32_t *buf, uint32_t number, int32_t *reture_value)
{
    uint32_t i = 0, j = 0;
    int32_t tmp_value = 0;
    for (j = 0; j < (number - 1); j++)
    {
        for (i = 0; i < (number - j - 1); i++)
        {
            if (buf[i] > buf[i + 1])
            {
                tmp_value = buf[i];
                buf[i] = buf[i + 1];
                buf[i + 1] = tmp_value;
            }
        }
    }
    *reture_value = (number - 1) / 2;
}

/*
        算术平均滤波法
    buf：数据列表
    number：数据数量，为奇数
    reture_value：返回值
*/
void qyq_arithmetic_average_filter(int32_t *buf, uint32_t number, int32_t *reture_value)
{
    uint32_t i = 0;
    int32_t sum = 0;

    for (i = 0; i < number; i++)
    {
        sum += buf[i];
    }
    *reture_value = sum / number;
}

/*
        递推平均滤波法
    new_value：新的值
    buf：数据列表
    number：数据数量，为奇数
    reture_value：返回值
*/
void qyq_arithmetic_recursive_average_filter(int32_t new_value, int32_t *buf, uint32_t number, int32_t *reture_value)
{
    uint32_t i = 0;
    int32_t sum = 0;

    for (i = 0; i < number - 1; i++)
    {
        buf[i] = buf[i + 1];
    }
    buf[i] = new_value;
    for (i = 0; i < number; i++)
    {
        sum += buf[i];
    }
    *reture_value = sum / number;
}

/*
        中位值平均滤波法
    buf：数据列表
    number：数据数量
    rejection_value：剔除数量*2
    reture_value：返回值
*/
void qyq_arithmetic_median_average_filter(int32_t *buf, uint32_t number, uint32_t rejection_value, int32_t *reture_value)
{
    int32_t sum = 0;
    uint32_t i = 0, j = 0;
    int32_t tmp_value = 0;
    // 排序
    for (j = 0; j < (number - 1); j++)
    {
        for (i = 0; i < (number - j - 1); i++)
        {
            if (buf[i] > buf[i + 1])
            {
                tmp_value = buf[i];
                buf[i] = buf[i + 1];
                buf[i + 1] = tmp_value;
            }
        }
    }

    // 求平均值
    for (i = rejection_value; i < number - rejection_value; i++)
    {
        sum += buf[i];
    }
    *reture_value = sum / (number - rejection_value * 2);
}

/*
        限幅平均滤波法
    old_value：旧的值
    new_value：新的值
    deviation_value：偏差值
    buf：数据列表
    number：数据数量，为奇数
    reture_value：返回值
*/
void qyq_arithmetic_limiting_average_filter(int32_t old_value, int32_t new_value, int32_t deviation_value, int32_t *buf, uint32_t number, int32_t *reture_value)
{
    uint32_t i = 0;
    int32_t sum = 0;
    if (old_value < new_value)
    {
        if ((new_value - old_value) < deviation_value)
        {
            for (i = 0; i < number - 1; i++)
            {
                buf[i] = buf[i + 1];
            }
            buf[i] = new_value;
        }
    }
    else
    {
        if ((old_value - new_value) < deviation_value)
        {
            for (i = 0; i < number - 1; i++)
            {
                buf[i] = buf[i + 1];
            }
            buf[i] = new_value;
        }
    }

    for (i = 0; i < number; i++)
    {
        sum += buf[i];
    }
    *reture_value = sum / number;
}

/*
        一阶滞后滤波法
    old_value：旧的值
    new_value：新的值
    a_value：a值，取值为0-100，放大100倍
    reture_value：返回值
*/
void qyq_arithmetic_lagging_filter(int32_t old_value, int32_t new_value, uint8_t a_value, int32_t *reture_value)
{
    *reture_value = (100 - a_value) * new_value + a_value * old_value;
}

/*
        加权递推平均滤波法
    new_value：新的值
    buf：数据列表
    number：数据数量，为奇数
    reture_value：返回值
*/
void qyq_arithmetic_weighted_recursive_average_filter(int32_t new_value, int32_t *buf, uint32_t number, int32_t *coe_list, int32_t *reture_value)
{
    uint32_t i = 0;
    int32_t sum = 0;
    int32_t coe_sum = 0;

    for (i = 0; i < number - 1; i++)
    {
        buf[i] = buf[i + 1];
    }
    buf[i] = new_value;

    for (i = 0; i < number; i++)
    {
        coe_sum += coe_list[i];
        sum += buf[i] * coe_list[i];
    }
    *reture_value = sum / coe_sum;
}

/*
        消抖滤波法
    old_value：旧的值
    new_value：新的值
    count：静态计数器
    number：对比数量
    reture_value：返回值
*/
void qyq_arithmetic_buffeting_filter(int32_t old_value, int32_t new_value, uint32_t *count, uint32_t number, int32_t *reture_value)
{
    if (old_value != new_value)
    {
        (*count)++;
        if ((*count) >= number)
        {
            *reture_value = new_value;
        }
    }
    else
    {
        (*count) = 0;
        *reture_value = old_value;
    }
}

/*
        限幅消抖滤波法
    old_value：旧的值
    new_value：新的值
    deviation_value：偏差值
    count：静态计数器
    number：对比数量
    reture_value：返回值
*/
void qyq_arithmetic_limiting_buffeting_filter(int32_t old_value, int32_t new_value, int32_t deviation_value, uint32_t *count, uint32_t number, int32_t *reture_value)
{
    if (old_value != new_value)
    {
        if (old_value < new_value)
        {
            if ((new_value - old_value) > deviation_value)
            {
                *reture_value = old_value;
            }
            else
            {
                (*count)++;
                if ((*count) >= number)
                {
                    *reture_value = new_value;
                }
            }
        }
        else
        {
            if ((old_value - new_value) > deviation_value)
            {
                *reture_value = old_value;
            }
            else
            {
                (*count)++;
                if ((*count) >= number)
                {
                    *reture_value = new_value;
                }
            }
        }
    }
    else
    {
        (*count) = 0;
        *reture_value = old_value;
    }
}
